package com.yanqu.road.dao.impl.beautyescort;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.dao.db.DbParameter;
import com.yanqu.road.dao.impl.TempDataObjectDao;
import com.yanqu.road.entity.beautyescort.EnemyInfo;
import com.yanqu.road.entity.beautyescort.EscortBeatBack;
import com.yanqu.road.entity.beautyescort.EscortReport;
import com.yanqu.road.utils.string.StringUtils;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class EscortReportDaoImpl extends TempDataObjectDao<EscortReport> {


    public static String getEscortReportSql = "select * from `t_c_escort_report` where `weekId`=? and del = 0";
    public Map<Long, Map<Long, EscortReport>> getEscortReport(int weekId) {
        ResultSet rs = null;
        CallableStatement call = null;
        Map<Long, Map<Long, EscortReport>> result = new ConcurrentHashMap<>();
        try {
            getDb().setConnName(DbNameStrategy.getCrossDb());
            call = getDb().getConnection().prepareCall(getEscortReportSql);
            int i = 1;
            call.setInt(i++, weekId);
            rs = call.executeQuery();
            while (rs.next()) {
                EscortReport data = parse(rs);
                fixData(data);
                if(!result.containsKey(data.getUserId())){
                    result.put(data.getUserId(), new ConcurrentHashMap<>());
                }
                result.get(data.getUserId()).put(data.getDartId(), data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);} finally {
            getDb().closeConnection(call, rs);
        }
        return result;
    }

    private void fixData(EscortReport data){
        if (data.getEnemy().size() > 0) {
            List<EnemyInfo> enemyInfoList = new ArrayList<>();
            // 迁移旧数据
            for (Long uid : data.getEnemy()) {
                EnemyInfo enemyInfo = new EnemyInfo();
                enemyInfo.setUserId(uid);
                enemyInfo.setTime(0);
                enemyInfoList.add(enemyInfo);
            }
            // 清空
            data.setEnemy(new ArrayList<>());
            data.setEnemyInfoList(enemyInfoList);
        }
    }

    public static String insertEscortReportSql = "insert into `t_c_escort_report`(userId,serverId,dartId,weekId,dartType,enemy,reward,eventId,robbedTimes,startTime,latestRobTime,beatBack,del,enemyInfoList) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
    @Override
    protected boolean addData(EscortReport data) {
        data.setBeginWriteTime();
        getDb().setConnName(DbNameStrategy.getCrossDb());
        int i = 1;
        Map<Integer, DbParameter> para = new HashMap<Integer, DbParameter>();
        para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
        para.put(i++, new DbParameter(Types.BIGINT, data.getServerId()));
        para.put(i++, new DbParameter(Types.BIGINT, data.getDartId()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getWeekId()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getDartType()));
        para.put(i++, new DbParameter(Types.VARCHAR, StringUtils.listToString(data.getEnemy(), ",")));
        para.put(i++, new DbParameter(Types.VARCHAR, data.getReward()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getEventId()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getRobbedTimes()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getStartTime()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getLatestRobTime()));
        para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getBeatBack())));
        para.put(i++, new DbParameter(Types.BOOLEAN, data.isDel()));
        para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getEnemyInfoList())));
        if (getDb().executeNoneQuery(insertEscortReportSql, para) > 0) {
            return true;
        }
        return false;
    }


    public static String updateEscortReportSql = "update `t_c_escort_report` set serverId=?,weekId=?,dartType=?,enemy=?,reward=?,eventId=?,robbedTimes=?,startTime=?,latestRobTime=?,beatBack=?,del=?,enemyInfoList=? where userId=? and dartId=?";
    @Override
    protected boolean updateData(EscortReport data) {
        data.setBeginWriteTime();
        getDb().setConnName(DbNameStrategy.getCrossDb());
        int i = 1;
        Map<Integer, DbParameter> para = new HashMap<Integer, DbParameter>();
        para.put(i++, new DbParameter(Types.BIGINT, data.getServerId()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getWeekId()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getDartType()));
        para.put(i++, new DbParameter(Types.VARCHAR, StringUtils.listToString(data.getEnemy(), ",")));
        para.put(i++, new DbParameter(Types.VARCHAR, data.getReward()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getEventId()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getRobbedTimes()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getStartTime()));
        para.put(i++, new DbParameter(Types.INTEGER, data.getLatestRobTime()));
        para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getBeatBack())));
        para.put(i++, new DbParameter(Types.BOOLEAN, data.isDel()));
        para.put(i++, new DbParameter(Types.VARCHAR, JSON.toJSONString(data.getEnemyInfoList())));
        para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
        para.put(i++, new DbParameter(Types.BIGINT, data.getDartId()));
        if (getDb().executeNoneQuery(updateEscortReportSql, para) > 0) {
            return true;
        }
        return false;
    }

    @Override
    protected EscortReport parseData(ResultSet rs) throws SQLException {
        EscortReport data = new EscortReport();
        data.setUserId(rs.getLong("userId"));
        data.setServerId(rs.getLong("serverId"));
        data.setDartId(rs.getLong("dartId"));
        data.setDartType(rs.getInt("dartType"));
        data.setWeekId(rs.getInt("weekId"));
        data.setEnemy(StringUtils.stringToLongList(rs.getString("enemy"), ","));
        String enemyInfoListStr = rs.getString("enemyInfoList");
        if (!StringUtils.isNullOrEmpty(enemyInfoListStr)) {
            data.setEnemyInfoList(JSON.parseObject(enemyInfoListStr, new TypeReference<List<EnemyInfo>>() {
            }));
        }
        data.setReward(rs.getString("reward"));
        data.setEventId(rs.getInt("eventId"));
        data.setRobbedTimes(rs.getInt("robbedTimes"));
        data.setStartTime(rs.getInt("startTime"));
        data.setLatestRobTime(rs.getInt("latestRobTime"));
        data.setDel(rs.getBoolean("del"));
        String val = rs.getString("beatBack");
        if(!StringUtils.isNullOrEmpty(val)){
            data.setBeatBack(JSON.parseObject(val, new TypeReference<Map<Long, EscortBeatBack>>() {}));
        }
        return data;
    }
}
